/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


/*************************************************************************
 *\author: starlove
 *************************************************************************/
#ifndef __CC_PYTHON_IMPORT_IMPL_IMPL__
#define __CC_PYTHON_IMPORT_IMPL_IMPL__

#pragma GCC diagnostic ignored "-Wwrite-strings"

#include <cocos2d.h>
#include <cocos-ext.h>

#include <extensions/data_implement.hpp>

USING_NS_CC;
USING_NS_CC_EXT;

#include <python_import_impl.h>
#include <objects/python_object_output.hpp>
#include <objects/python_object_director.hpp>
#include <objects/python_object_nodeobjects.hpp>
#include <objects/python_object_layer.hpp>
#include <objects/python_object_sprite.hpp>
#include <objects/python_object_scale9sprite.hpp>
#include <objects/python_object_image.hpp>
#include <objects/python_object_texture2d.hpp>
#include <objects/python_object_textureatlas.hpp>
#include <objects/python_object_spritebatchnode.hpp>
#include <objects/python_object_spriteframe.hpp>
#include <objects/python_object_touch.hpp>
#include <objects/python_object_labelttf.hpp>
#include <objects/python_object_labelbmfont.hpp>
#include <objects/python_object_atlasnode.hpp>
#include <objects/python_object_labelatlas.hpp>
#include <objects/python_object_eglview.hpp>
#include <objects/python_object_scheduler.hpp>
#include <objects/python_object_action.hpp>
#include <objects/python_object_caches.hpp>
#include <objects/python_object_fileutils.hpp>
#include <objects/python_object_menu.hpp>
#include <objects/python_object_transition.hpp>
#include <objects/python_object_audio.hpp>
#include <objects/python_object_particle.hpp>
#include <objects/python_object_protocols.hpp>
#include <objects/python_object_ext_scrollview.hpp>
#include <extensions/network.hpp>
#include <extensions/singleton.hpp>

NS_CCPY_BEGIN
	
PYCLASS_INIT(CPyClassBase, "ClassBase");
LPCPyClassBase CPyModule::m_pClassBase = NULL;

#define ENUM_REGISTER(n) module.RegisterIntValue(#n, n)

#define CC_ENUM_REGISTER(n) module.RegisterIntValue(#n, cocos2d::n)

#define CC_ENUM_REGISTER_FOR(n, p) module.RegisterIntValue(n, p)

void CPythonImportImpl::RegisterObjects()
{
	CPyModule module("cocos2d", "A python wrapper for cocos2d-x");
	
	module.RegisterClass<CPyRGBAProtocol>();
	module.RegisterClass<CPyBlendProtocol>();
	module.RegisterClass<CPyTextureProtocol>();
	module.RegisterClass<CPyLabelProtocol>();
	module.RegisterClass<CPyTouchDelegate>();
	module.RegisterClass<CPyAccelerometerDelegate>();
	module.RegisterClass<CPyKeypadDelegate>();
	module.RegisterClass<CPyOutput>();
	module.RegisterClass<CPyDirector>();
	module.RegisterClass<CPyCCObject>();
	module.RegisterClass<CPyNode>();
	module.RegisterClass<CPyNodeRGBA>();
	module.RegisterClass<CPyScene>();
	module.RegisterClass<CPyLayer>();
	module.RegisterClass<CPyLayerRGBA>();
	module.RegisterClass<CPyLayerColor>();
	module.RegisterClass<CPySprite>();
	module.RegisterClass<CPyScale9Sprite>();
	module.RegisterClass<CPyImage>();
	module.RegisterClass<CPyTexture2D>();
	module.RegisterClass<CPyTextureAtlas>();
	module.RegisterClass<CPySpriteFrame>();
	module.RegisterClass<CPySpriteBatchNode>();
	module.RegisterClass<CPyParticleSystem>();
	module.RegisterClass<CPyParticleSystemQuad>();
	module.RegisterClass<CPyParticleFire>();
	module.RegisterClass<CPyParticleFireworks>();
	module.RegisterClass<CPyParticleSun>();
	module.RegisterClass<CPyParticleGalaxy>();
	module.RegisterClass<CPyParticleFlower>();
	module.RegisterClass<CPyParticleMeteor>();
	module.RegisterClass<CPyParticleSpiral>();
	module.RegisterClass<CPyParticleExplosion>();
	module.RegisterClass<CPyParticleSmoke>();
	module.RegisterClass<CPyParticleSnow>();
	module.RegisterClass<CPyParticleRain>();
	module.RegisterClass<CPyLabelTTF>();
	module.RegisterClass<CPyLabelBMFont>();
	module.RegisterClass<CPyAtlasNode>();
	module.RegisterClass<CPyLabelAtlas>();
	module.RegisterClass<CPyEGLView>();
	module.RegisterClass<CPyTimer>();
	module.RegisterClass<CPyAction>();
	module.RegisterClass<CPyFiniteTimeAction>();
	module.RegisterClass<CPySpeed>();
	module.RegisterClass<CPyFollow>();
	module.RegisterClass<CPyActionInterval>();
	module.RegisterClass<CPySequence>();
	module.RegisterClass<CPyRepeat>();
	module.RegisterClass<CPyRepeatForever>();
	module.RegisterClass<CPySpawn>();
	module.RegisterClass<CPyRotateTo>();
	module.RegisterClass<CPyRotateBy>();
	module.RegisterClass<CPyMoveBy>();
	module.RegisterClass<CPyMoveTo>();
	module.RegisterClass<CPySkewTo>();
	module.RegisterClass<CPySkewBy>();
	module.RegisterClass<CPyJumpBy>();
	module.RegisterClass<CPyJumpTo>();
	module.RegisterClass<CPyBezierBy>();
	module.RegisterClass<CPyBezierTo>();
	module.RegisterClass<CPyScaleTo>();
	module.RegisterClass<CPyScaleBy>();
	module.RegisterClass<CPyBlink>();
	module.RegisterClass<CPyFadeIn>();
	module.RegisterClass<CPyFadeOut>();
	module.RegisterClass<CPyFadeTo>();
	module.RegisterClass<CPyTintBy>();
	module.RegisterClass<CPyTintTo>();
	module.RegisterClass<CPyDelayTime>();
	module.RegisterClass<CPyReverseTime>();
	module.RegisterClass<CPyAnimation>();
	module.RegisterClass<CPyAnimate>();
	module.RegisterClass<CPyTargetedAction>();
	module.RegisterClass<CPyActionInstant>();
	module.RegisterClass<CPyShow>();
	module.RegisterClass<CPyHide>();
	module.RegisterClass<CPyToggleVisibility>();
	module.RegisterClass<CPyRemoveSelf>();
	module.RegisterClass<CPyFlipX>();
	module.RegisterClass<CPyFlipY>();
	module.RegisterClass<CPyPlace>();
	module.RegisterClass<CPyCallFunc>();
	module.RegisterClass<CPyActionManager>();
	module.RegisterClass<CPyTouch>();
	module.RegisterClass<CPyPoint>();
	module.RegisterClass<CPySize>();
	module.RegisterClass<CPyRect>();
	module.RegisterClass<CPyColor3B>();
	module.RegisterClass<CPyColor4B>();
	module.RegisterClass<CPyColor4F>();
	module.RegisterClass<CPyVertex2F>();
	module.RegisterClass<CPyVertex3F>();
	module.RegisterClass<CPyTex2F>();
	module.RegisterClass<CPyBlendFunc>();
	module.RegisterClass<CPyTexParams>();
	module.RegisterClass<CPyPointSprite>();
	module.RegisterClass<CPyQuad2>();
	module.RegisterClass<CPyQuad3>();
	module.RegisterClass<CPyV2F_C4B_T2F>();
	module.RegisterClass<CPyV2F_C4F_T2F>();
	module.RegisterClass<CPyV3F_C4B_T2F>();
	//module.RegisterClass<CPyV2F_C4B_T2F_Triangle>();
	module.RegisterClass<CPyV2F_C4B_T2F_Quad>();
	module.RegisterClass<CPyV3F_C4B_T2F_Quad>();
	module.RegisterClass<CPyV2F_C4F_T2F_Quad>();
	module.RegisterClass<CPyT2F_Quad>();
	module.RegisterClass<CPyAnimationCache>();
	module.RegisterClass<CPySpriteFrameCache>();
	module.RegisterClass<CPyTextureCache>();
	module.RegisterClass<CPyFileUtils>();
	module.RegisterClass<CPyMenu>();
	module.RegisterClass<CPyMenuItem>();
	module.RegisterClass<CPyMenuItemLabel>();
	module.RegisterClass<CPyMenuItemAtlasFont>();
	module.RegisterClass<CPyMenuItemFont>();
	module.RegisterClass<CPyMenuItemSprite>();
	module.RegisterClass<CPyMenuItemImage>();
	module.RegisterClass<CPyMenuItemToggle>();
	module.RegisterClass<CPyTransitionEaseScene>();
	module.RegisterClass<CPyTransitionScene>();
	module.RegisterClass<CPyTransitionSceneOriented>();
	module.RegisterClass<CPyTransitionRotoZoom>();
	module.RegisterClass<CPyTransitionJumpZoom>();
	module.RegisterClass<CPyTransitionMoveInL>();
	module.RegisterClass<CPyTransitionMoveInR>();
	module.RegisterClass<CPyTransitionMoveInT>();
	module.RegisterClass<CPyTransitionMoveInB>();
	module.RegisterClass<CPyTransitionSlideInL>();
	module.RegisterClass<CPyTransitionSlideInR>();
	module.RegisterClass<CPyTransitionSlideInT>();
	module.RegisterClass<CPyTransitionSlideInB>();
	module.RegisterClass<CPyTransitionShrinkGrow>();
	module.RegisterClass<CPyTransitionFlipX>();
	module.RegisterClass<CPyTransitionFlipY>();
	module.RegisterClass<CPyTransitionFlipAngular>();
	module.RegisterClass<CPyTransitionZoomFlipX>();
	module.RegisterClass<CPyTransitionZoomFlipY>();
	module.RegisterClass<CPyTransitionZoomFlipAngular>();
	module.RegisterClass<CPyTransitionFade>();
	module.RegisterClass<CPyTransitionCrossFade>();
	module.RegisterClass<CPyTransitionTurnOffTiles>();
	module.RegisterClass<CPyTransitionSplitCols>();
	module.RegisterClass<CPyTransitionSplitRows>();
	module.RegisterClass<CPyTransitionFadeTR>();
	module.RegisterClass<CPyTransitionFadeBL>();
	module.RegisterClass<CPyTransitionFadeUp>();
	module.RegisterClass<CPyTransitionFadeDown>();
	module.RegisterClass<CPyTransitionPageTurn>();
	module.RegisterClass<CPyTransitionProgress>();
	module.RegisterClass<CPyTransitionProgressRadialCCW>();
	module.RegisterClass<CPyTransitionProgressRadialCW>();
	module.RegisterClass<CPyTransitionProgressHorizontal>();
	module.RegisterClass<CPyTransitionProgressVertical>();
	module.RegisterClass<CPyTransitionProgressInOut>();
	module.RegisterClass<CPyTransitionProgressOutIn>();
	//module.RegisterClass<CPyAnimationFrameData>();
	module.RegisterIntValue("CC_TARGET_PLATFORM", CC_TARGET_PLATFORM);
	module.RegisterIntValue("COCOS2D_VERSION", COCOS2D_VERSION);

	module.RegisterIntValue("CC_PLATFORM_UNKNOWN"	, CC_PLATFORM_UNKNOWN	);
	module.RegisterIntValue("CC_PLATFORM_IOS"		, CC_PLATFORM_IOS		);   
	module.RegisterIntValue("CC_PLATFORM_ANDROID"	, CC_PLATFORM_ANDROID	);   
	module.RegisterIntValue("CC_PLATFORM_WIN32"		, CC_PLATFORM_WIN32		);     
	module.RegisterIntValue("CC_PLATFORM_MARMALADE"	, CC_PLATFORM_MARMALADE	);
	module.RegisterIntValue("CC_PLATFORM_LINUX"		, CC_PLATFORM_LINUX		);  
	module.RegisterIntValue("CC_PLATFORM_BADA"		, CC_PLATFORM_BADA		);
	module.RegisterIntValue("CC_PLATFORM_BLACKBERRY", CC_PLATFORM_BLACKBERRY);
	module.RegisterIntValue("CC_PLATFORM_MAC"		, CC_PLATFORM_MAC		);     
	module.RegisterIntValue("CC_PLATFORM_NACL"		, CC_PLATFORM_NACL		);
	
	ENUM_REGISTER(kResolutionExactFit);
    ENUM_REGISTER(kResolutionNoBorder);
    ENUM_REGISTER(kResolutionShowAll);
    ENUM_REGISTER(kResolutionFixedHeight);
    ENUM_REGISTER(kResolutionFixedWidth);
    ENUM_REGISTER(kResolutionUnKnown);

	ENUM_REGISTER(kCCPrioritySystem);
    ENUM_REGISTER(kCCPriorityNonSystemMin);

    ENUM_REGISTER(kCCParticleDefaultCapacity);
	
	CC_ENUM_REGISTER(kCCTransitionOrientationLeftOver);
	CC_ENUM_REGISTER(kCCTransitionOrientationRightOver);
	CC_ENUM_REGISTER(kCCTransitionOrientationUpOver);
	CC_ENUM_REGISTER(kCCTransitionOrientationDownOver);

	CC_ENUM_REGISTER(kCCDirectorProjection2D);
    CC_ENUM_REGISTER(kCCDirectorProjection3D);
    CC_ENUM_REGISTER(kCCDirectorProjectionCustom);
    CC_ENUM_REGISTER(kCCDirectorProjectionDefault);

	CC_ENUM_REGISTER(kCCTouchesAllAtOnce);
    CC_ENUM_REGISTER(kCCTouchesOneByOne);
	
	CC_ENUM_REGISTER(kCCMenuStateWaiting);
	CC_ENUM_REGISTER(kCCMenuStateTrackingTouch);
	CC_ENUM_REGISTER(kCCMenuHandlerPriority);

	CC_ENUM_REGISTER(kCCVerticalTextAlignmentTop);
    CC_ENUM_REGISTER(kCCVerticalTextAlignmentCenter);
    CC_ENUM_REGISTER(kCCVerticalTextAlignmentBottom);

	CC_ENUM_REGISTER(kCCTextAlignmentLeft);
    CC_ENUM_REGISTER(kCCTextAlignmentCenter);
    CC_ENUM_REGISTER(kCCTextAlignmentRight);

	CC_ENUM_REGISTER(kCCParticleDurationInfinity);
	CC_ENUM_REGISTER(kCCParticleStartSizeEqualToEndSize);
	CC_ENUM_REGISTER(kCCParticleStartRadiusEqualToEndRadius);
	CC_ENUM_REGISTER(kParticleStartSizeEqualToEndSize);
	CC_ENUM_REGISTER(kParticleDurationInfinity);
	CC_ENUM_REGISTER(kCCParticleModeGravity);
	CC_ENUM_REGISTER(kCCParticleModeRadius);
	CC_ENUM_REGISTER(kCCPositionTypeFree);
	CC_ENUM_REGISTER(kCCPositionTypeRelative);
	CC_ENUM_REGISTER(kCCPositionTypeGrouped);
	CC_ENUM_REGISTER(kPositionTypeFree);
	CC_ENUM_REGISTER(kPositionTypeGrouped);
	
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_RGBA8888);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_RGB888);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_RGB565);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_A8);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_I8);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_AI88);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_RGBA4444);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_RGB5A1);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_PVRTC4);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_PVRTC2);
    CC_ENUM_REGISTER(kCCTexture2DPixelFormat_Default);
    CC_ENUM_REGISTER(kTexture2DPixelFormat_RGBA8888);
    CC_ENUM_REGISTER(kTexture2DPixelFormat_RGB888);
    CC_ENUM_REGISTER(kTexture2DPixelFormat_RGB565);
    CC_ENUM_REGISTER(kTexture2DPixelFormat_A8);
    CC_ENUM_REGISTER(kTexture2DPixelFormat_RGBA4444);
    CC_ENUM_REGISTER(kTexture2DPixelFormat_RGB5A1);
    CC_ENUM_REGISTER(kTexture2DPixelFormat_Default);
	
	CC_ENUM_REGISTER_FOR("ccimage_kAlignCenter", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kAlignTop", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kAlignTopRight", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kAlignRight", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kAlignBottomRight", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kAlignBottom", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kAlignBottomLeft", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kAlignLeft", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kAlignTopLeft", cocos2d::CCImage::kAlignCenter);
		
    CC_ENUM_REGISTER_FOR("ccimage_kFmtJpg", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kFmtPng", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kFmtTiff", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kFmtWebp", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kFmtRawData", cocos2d::CCImage::kAlignCenter);
    CC_ENUM_REGISTER_FOR("ccimage_kFmtUnKnown", cocos2d::CCImage::kAlignCenter);

	module.Embed();

    CPyOutput *pyOutput = NULL;
    pyOutput = (CPyOutput *)PyObject_New(CPyOutput, CPyClassBase::GetType<CPyOutput>());
    if(!pyOutput)
    {
        cocos2d::CCLog("set stdout: pyOutput new fail!");
        return;
    }

    pyOutput = new(pyOutput) CPyOutput("[python]");
    Py_INCREF(pyOutput);
    PySys_SetObject((char *)"stdout",(PyObject *)pyOutput);
    cocos2d::CCLog("(stdout) already redirect.");
	
    pyOutput = (CPyOutput *)PyObject_New(CPyOutput, CPyClassBase::GetType<CPyOutput>());
    if(!pyOutput)
    {
        cocos2d::CCLog("set stderr: pyOutput new fail!");
        return;
    }
    pyOutput = new(pyOutput) CPyOutput("[python-error]");
    Py_INCREF(pyOutput);
    PySys_SetObject((char *)"stderr",(PyObject *)pyOutput);
    cocos2d::CCLog("(stderr) already redirect.");
}

void CPythonImportImpl::RegisterDenshionObjects()
{
	CPyModule module("CocosDenshion", "A python wrapper for cocos2d-x CocosDenshion");
	module.RegisterClass<CPySimpleAudioEngine>();
	module.Embed();
}

void CPythonImportImpl::RegisterExtensionObjects()
{
	CPyModule module("cocos2d.extension", "A python wrapper for cocos2d-x extension");
	module.RegisterClass<CPyScrollView>();
	module.RegisterClass<CPyScrollViewDelegate>();
	module.RegisterClass<CPyTableView>();
	module.RegisterClass<CPyTableViewCell>();
	module.RegisterClass<CPyTableViewDelegate>();
	module.RegisterClass<CPyTableViewDataSource>();
	module.RegisterClass<CPyNetwork>();
	ENUM_REGISTER(kCCScrollViewDirectionNone);
    ENUM_REGISTER(kCCScrollViewDirectionHorizontal);
    ENUM_REGISTER(kCCScrollViewDirectionVertical);
    ENUM_REGISTER(kCCScrollViewDirectionBoth);
    ENUM_REGISTER(kCCTableViewFillTopDown);
    ENUM_REGISTER(kCCTableViewFillBottomUp);
	module.Embed("cocos2d", "extension");
}
NS_CCPY_END

#endif